package utils
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.SharedObject;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;

	import mx.graphics.codec.JPEGEncoder;
	import mx.graphics.codec.PNGEncoder;

	public class FilesUtil
	{

		public static const PNG:String="png";
		public static const JPG:String="jpg";

		static public function getYearDate():String
		{
			var now:Date=new Date();
			var year:String=now.fullYear + "";
			var month:String=pad(int(now.getMonth() + 1) + "", 2) + "";
			var date:String=pad(int(now.getDate()) + "", 2) + "";
			var hh:String=pad(int(now.hours) + "", 2) + "";
			var mm:String=pad(int(now.minutes) + "", 2) + "";
			var ss:String=pad(int(now.seconds) + "", 2) + "";
			//月日时分
			return year + month + date + hh + mm + ss;
		}

		static private function pad(num:String, n:int):String
		{
			if ((num + "").length >= n)
			{
				return num;
			}
			return pad("0" + num, n);
		}

		/**
		 * 利用递归来查找在某个文件夹下是否存在fileName为名的文件
		 * @param nativePath:String 要查找 的文件夹路径
		 * @param fileName:String 要查找的文件名称
		 * @return 查找成功则返回true
		 *
		 */
		public static function checkFileIsExit(nativePath:String, fileName:String=null):Boolean
		{
			var file:File=new File(nativePath);

			if (fileName == null)
			{
				return file.exists;
			}

			//查找文件夹下的文件
			var list:Array=file.getDirectoryListing();
			var len:int=list.length;

			for (var i:int=0; i < len; i++)
			{
				var cfile:File=list[i] as File;

				if (cfile.isDirectory)
				{
					if (checkFileIsExit(cfile.nativePath, fileName))
						return true;
						//checkFileIsExit(cfile.nativePath,fileName);
				}
				else
				{
					if (cfile.name == fileName)
					{
						trace("找到了", cfile.nativePath);
						return true;
					}
				}
			}
			trace("没找到", nativePath);
			return false;
		}

		/**
		 * 获得最终子文件夹下的内容
		 * @param nativePath:String
		 * @return
		 *
		 */
		public static function getLastDirectoryFiles(nativePath:String):Array
		{
			var filesArray:Array=new Array();
			var file:File=new File(nativePath);

			//查找文件夹下的文件
			var list:Array=file.getDirectoryListing();
			var len:int=list.length;

			for (var i:int=0; i < len; i++)
			{
				var cfile:File=list[i] as File;

				if (cfile.isDirectory)
				{
					filesArray=getLastDirectoryFiles(cfile.nativePath);

					if (filesArray != null)
						break;
				}
				else
				{
					if (cfile.name.indexOf(".png") != -1)
					{
						filesArray.push(cfile.name);
					}
				}
			}
			return filesArray;
		}


		/**
		 * 保存切割的位图 为PNG
		 * @param bmd 要保存的BitmapData数据
		 * @param nativePath 要保存的文件完整路径
		 * @param type 要保存的文件类型 Files.PNG || Files.JPG
		 * @param overwrite 是否覆盖已有的文件
		 * @param clear 是否自动清除内存
		 */
		public static function saveBmp(bmd:BitmapData, nativePath:String, type:String=FilesUtil.PNG, overwrite:Boolean=true, clear:Boolean=true):void
		{

			try
			{
				var file:File=new File(nativePath);

				if (file.exists && !overwrite)
				{
//					trace("已经存在了,不覆盖返回")
					file=null;
					return;
				}

				var bytes:ByteArray;

				switch (type)
				{
					case FilesUtil.PNG:
						var pngEncoder:PNGEncoder=new PNGEncoder();
						bytes=pngEncoder.encode(bmd);
						pngEncoder=null;
						break;
					case FilesUtil.JPG:
						var jpgEncoder:JPEGEncoder=new JPEGEncoder(60);
						bytes=jpgEncoder.encode(bmd);
						jpgEncoder=null;
						break;
					default:
						break;
				}


				//var pngEncoder:AsPngEncoder = new AsPngEncoder();
				//var bytes:ByteArray = pngEncoder.encode(bmd, new Strategy8BitMedianCutAlpha());

				var stream:FileStream=new FileStream();
				stream.open(file, FileMode.WRITE);
				stream.writeBytes(bytes, 0, bytes.length);
				stream.close();

				trace("保存完", nativePath);

				if (clear)
					bmd.dispose();
				bmd=null;

				bytes.clear();
				bytes=null;
				file=null;
			}
			catch (e:Error)
			{
				trace("保存出错", e);
			}
		}

		/**
		 * 通用存储函数
		 * @param nativePath
		 * @param value 可以为Array，Object,String,ByteArray
		 * @param overwrite
		 * @param compress
		 *
		 */
		public static function saveToFile(nativePath:String, value:*, overwrite:Boolean=true, compress:Boolean=false):void
		{
			try
			{
				if (value == "" || value == null || nativePath == "")
				{
					trace("非法传值");
					return;
				}

				var file:File=new File(nativePath);

				if (file.exists && !overwrite)
				{
					file=null;
					return;
				}

				var stream:FileStream=new FileStream();

				var bytes:ByteArray=new ByteArray();

				if (value is Array)
				{
					bytes.writeObject(value);
				}
				else if (value is String)
				{
					bytes.writeUTFBytes(value);
				}
				else if (value is XML)
				{
					bytes.writeUTFBytes((value as XML).toXMLString());
				}
				else if (value is ByteArray)
				{
					bytes.writeBytes(value, 0, value.length);
						//					bytes = value as ByteArray;
				}
				else if (value is int)
				{
					bytes.writeInt(value);
				}
				else if (value is Number)
				{
					bytes.writeFloat(value);
				}
				else if (value is uint)
				{
					bytes.writeUnsignedInt(value);
				}
				else
				{
					bytes.writeObject(value);
				}

				//				
				if (compress)
				{
					trace("压缩前长度", bytes.length);
					bytes.compress();
					trace("压缩后长度", bytes.length);
				}


				stream.open(file, FileMode.WRITE);
				stream.writeBytes(bytes, 0, bytes.length); //使包括汉字时不会有错 gb2123 为汉字编码
				stream.close();

				bytes.clear();
				bytes=null;

					//trace("保存完", nativePath);
			}
			catch (e:Error)
			{
				trace("保存出错", e);
			}
		}


		/**
		 * 保存一份字符串到硬盘
		 * @param nativePath 包括文件后缀名的完整路径
		 * @param value 要保存的字符串
		 * @param type  表示输出UTF-8 或 gb2123
		 * @param overwrite 是否覆盖已有的文件
		 */
		public static function saveUTFBytesToFile(nativePath:String, value:String, type:String="UTF-8", overwrite:Boolean=true):Boolean
		{
			try
			{
				if (value == "" || nativePath == "")
				{
					trace("非法传值");
					return false;
				}

				var file:File=new File(nativePath);

				if (file.exists && !overwrite)
				{
					trace("已经存在了,不覆盖,返回");
					file=null;
					return false;
				}

				var stream:FileStream=new FileStream();
				stream.open(file, FileMode.WRITE);
				stream.writeMultiByte(value, type); //使包括汉字时不会有错 gb2123 为汉字编码
				stream.close();

				trace("保存完", nativePath);
			}
			catch (e:Error)
			{
				trace("保存出错", e);
				return false;
			}

			return true;
		}


		/**
		 * 保存一份被压缩的字符串到硬盘
		 * @param nativePath 包括文件后缀名的完整路径
		 * @param str 要保存的字符串
		 * @param overwrite 是否覆盖已有的文件
		 * @param type  表示输出UTF-8 或 gb2123
		 *
		 */
		public static function saveCompressUTFBytesToFile(nativePath:String, value:String, type:String="UTF-8", overwrite:Boolean=true):void
		{
			if (value == "" || nativePath == "")
			{
				trace("非法传值");
				return;
			}

			var file:File=new File(nativePath);

			if (file.exists && !overwrite)
			{
				trace("已经存在了,不覆盖,返回");
				file=null;
				return;
			}

			var stream:FileStream=new FileStream();

			var bytes:ByteArray=new ByteArray();
			bytes.writeMultiByte(value, type);
			bytes.compress();


			stream.open(file, FileMode.WRITE);
			stream.writeBytes(bytes, 0, bytes.length); //使包括汉字时不会有错 gb2123 为汉字编码
			stream.close();
		}


		/**
		 * 读取硬盘某个文件的字符串数据
		 * @param nativePath 文件路径
		 * @param 是否是要解压缩文件
		 * @return 返回字符串
		 *
		 */
		public static function getUTFBytesFromFile(nativePath:String, unCompress:Boolean=false):String
		{
			var bytes:ByteArray=getBytesFromeFile(nativePath, unCompress);
			var value:String=bytes.readUTFBytes(bytes.length);
			return value;
		}

		/**
		 * 从某个文件中读取二制流
		 * @param nativePath
		 * @param unCompress 是否是要解压缩文件
		 * @return 返回二进制流
		 *
		 */
		public static function getBytesFromeFile(nativePath:String, unCompress:Boolean=false):ByteArray
		{
			var bytes:ByteArray=new ByteArray();

			var file:File=new File(nativePath);
			var stream:FileStream=new FileStream();
			stream.open(file, FileMode.READ);
			stream.readBytes(bytes, 0, stream.bytesAvailable);
			stream.close();

			if (unCompress)
			{
				bytes.uncompress();
			}
			return bytes;
		}

		/**
		 * 保存2进制文件
		 * @param savePath
		 * @param bytes
		 *
		 */
		public static function saveBytes(file:File, bytes:ByteArray, compress:Boolean=false, isEncrypt:Boolean=false, offset:int=0):void
		{
			bytes.position=0;
			if (isEncrypt)
			{
				bytes=encryptByteArray(bytes);
			}

			if (compress)
			{
				bytes.compress();
			}
			var stream:FileStream=new FileStream();
			stream.open(file, FileMode.WRITE);
			stream.writeBytes(bytes, offset, bytes.length - offset);
			stream.close();
		}

		public static function saveSharedUrl(so:SharedObject, url:String):void
		{
			so.setProperty("url", url);
			so.flush();
		}

		public static function getSharedUrl(so:SharedObject):String
		{
			return so.data["url"];
		}

		/**
		 * 密文
		 */
		public static var key:String='2065223';

		/**
		 * 加密
		 * @param bytes
		 * @return
		 *
		 */
		public static function encryptByteArray(bytes:ByteArray):ByteArray
		{
			var encryptBytes:ByteArray=new ByteArray();
			var len:int=bytes.length;
			var keylen:int=key.length;
			var keys:Array=[];
			var flag:int=0;
			var i:int;

			for (i=0; i < keylen; i++)
			{
				keys.push(key.charCodeAt(i));
			}

			for (i=0; i < len; i++, flag++)
			{
				if (flag >= keylen)
				{
					flag=0;
				}
				encryptBytes.writeByte(bytes[i] + keys[flag]);
			}
			return encryptBytes;
		}

		/** 返回URL小写扩展名(如：jpg  png swf)*/
		public static function getExtension(url:String):String
		{
			var _extension:String=((url + "").split("?")[0]).split(".").reverse()[0];
			return _extension.toLocaleLowerCase();
		}

		/** 返回文件名 */
		public static function getFileName(url:String):String
		{
			var temp:String=(url + "").split("\\").join("/");
			var last:int=temp.lastIndexOf("/") + 1;
			return temp.substr(last, temp.length);
		}

		/** 返回文件路径 */
		public static function getDirName(url:String):String
		{
			var temp:String=(url + "").split("\\").join("/");
			var last:int=temp.lastIndexOf("/") + 1;
			var out:String=temp.substr(0, last);
			return out;
		}

		public static function deleteFile(nativePath:String):Boolean
		{
			try
			{
				var file:File=new File(nativePath);
				if (file.exists)
				{
					file.deleteFile();
					return true;
				}
			}
			catch (error:Error)
			{
			}
			return false;
		}

		/**
		 * 加载文件图片
		 * @param nativePath
		 * @param complete
		 *
		 */
		public static function getBitmapForFile(file:File, complete:Function, ... args):Boolean
		{
			if (file == null || file.isDirectory)
			{
				return false;
			}
			var exts:String=file.extension.toLocaleLowerCase();
			//只支持png和jpg
			if (exts != "png" && exts != "jpg")
			{
				return false;
			}
			var byte:ByteArray=getBytesFromeFile(file.nativePath);
			var loader:Loader=new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void
			{
				var bitmap:Bitmap=LoaderInfo(e.target).content as Bitmap;
				byte.clear();
				if (args.length > 0)
				{
					complete(bitmap, args);
				}
				else
				{
					complete(bitmap);
				}
				complete=null;
				byte=null;
			});
			var context:LoaderContext=new LoaderContext();
			context.allowCodeImport=true;
			loader.loadBytes(byte, context);
			return true;
		}

		/**
		 * 解密
		 * @param bytes
		 * @return
		 *
		 */
		public static function decryptByteArray(bytes:ByteArray):ByteArray
		{
			var decryptBytes:ByteArray=new ByteArray();
			var len:int=bytes.length;
			var keylen:int=key.length;
			var keys:Array=[];
			var flag:int=0;
			var i:int;

			for (i=0; i < keylen; i++)
			{
				keys.push(key.charCodeAt(i));
			}

			for (i=0; i < len; i++, flag++)
			{
				if (flag >= keylen)
				{
					flag=0;
				}
				decryptBytes.writeByte(bytes[i] - keys[flag]);
			}
			return decryptBytes;
		}
	}
}
